package com.ado.abyss.core.web.configure.cors;

import com.ado.abyss.core.web.security.JwtAuthenticationFilter;
import com.ado.abyss.core.web.security.JwtAuthenticationProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


import springfox.documentation.spring.web.SpringfoxWebMvcConfiguration;

/**
 *@author adonais
 *@date 2020年3月29日
 *@description CorsConfig.java
 **/
@Configuration
@ConditionalOnClass(SpringfoxWebMvcConfiguration.class)
public class CorsConfig extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {

	@Autowired
	private UserDetailsService userDetailsService;

	@Override
	public void configure(AuthenticationManagerBuilder auth) throws Exception {
		// 使用自定义身份验证组件
		auth.authenticationProvider(new JwtAuthenticationProvider(userDetailsService));
	}

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**")
		.allowedOrigins("*")
		.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
		.allowCredentials(true)
		.maxAge(3600)
		.allowedHeaders("*");
	}


	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		//        registry.addResourceHandler("/images/**").addResourceLocations("file:/root/Work/programmer/java/upload/");
		registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
		registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// 禁用 csrf, 由于使用的是JWT，我们这里不需要csrf
		http.cors().and().csrf().disable()
		.authorizeRequests()
		// 跨域预检请求
		.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
		// web jars
		.antMatchers("/webjars/**").permitAll()
		// knife4J
		.antMatchers("/doc.html/**").permitAll()
		// 查看SQL监控（druid）
		.antMatchers("/druid/**").permitAll()
		// 首页和登录页面
		.antMatchers("/").permitAll()
		.antMatchers("/api/login").permitAll()
		// swagger
		.antMatchers("/swagger-ui.html").permitAll()
		.antMatchers("/swagger-resources").permitAll()
		.antMatchers("/v2/api-docs").permitAll()
		.antMatchers("/webjars/springfox-swagger-ui/**").permitAll()
		// 验证码
		.antMatchers("/api/captcha.jpg**").permitAll()
		// 服务监控
		.antMatchers("/actuator/**").permitAll()
		// 其他所有请求需要身份认证
		.anyRequest().authenticated();
		// 退出登录处理器
		http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler());
		// token验证过滤器
		http.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);
	}

	@Bean
	@Override
	public AuthenticationManager authenticationManager() throws Exception {
		return super.authenticationManager();
	}

}